home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / hity wydania / Ubuntu 9.10 PL / karmelkowy-koliberek-desktop-9.10-i386-PL.iso / casper / filesystem.squashfs / usr / bin / savelog < prev    next >
Text File  |  2009-02-16  |  9KB  |  332 lines

  1. #! /bin/sh
  2. # savelog - save a log file
  3. #    Copyright (C) 1987, 1988 Ronald S. Karr and Landon Curt Noll
  4. #    Copyright (C) 1992  Ronald S. Karr
  5. # Slight modifications by Ian A. Murdock <imurdock@gnu.ai.mit.edu>:
  6. #    * uses `gzip' rather than `compress'
  7. #    * doesn't use $savedir; keeps saved log files in the same directory
  8. #    * reports successful rotation of log files
  9. #    * for the sake of consistency, files are rotated even if they are
  10. #      empty
  11. # More modifications by Guy Maor <maor@debian.org>:
  12. #       * cleanup.
  13. #       * -p (preserve) option
  14. # usage: savelog [-m mode] [-u user] [-g group] [-t] [-p] [-c cycle]
  15. #         [-j] [-C] [-d] [-l] [-r rolldir] [-n] [-q] file...
  16. #    -m mode      - chmod log files to mode
  17. #    -u user      - chown log files to user
  18. #    -g group  - chgrp log files to group
  19. #    -c cycle  - save cycle versions of the logfile    (default: 7)
  20. #    -r rolldir- use rolldir instead of . to roll files
  21. #    -C      - force cleanup of cycled logfiles
  22. #    -d      - use standard date for rolling
  23. #    -D      - override date format for -d 
  24. #    -t      - touch file
  25. #    -l      - don't compress any log files    (default: compress)
  26. #       -p        - preserve mode/user/group of original file
  27. #    -j        - use bzip2 instead of gzip
  28. #    -x script - invoke script with rotated log file in $FILE
  29. #    -n      - do not rotate empty files
  30. #    -q      - be quiet
  31. #    file       - log file names
  32. #
  33. # The savelog command saves and optionally compresses old copies of files.
  34. # Older version of 'file' are named:
  35. #
  36. #        'file'.<number><compress_suffix>
  37. #
  38. # where <number> is the version number, 0 being the newest.  By default,
  39. # version numbers > 0 are compressed (unless -l prevents it). The
  40. # version number 0 is never compressed on the off chance that a process
  41. # still has 'file' opened for I/O.
  42. #
  43. # if the '-d' option is specified, <number> will be YYMMDDhhmmss
  44. #
  45. # If the 'file' does not exist and -t was given, it will be created.
  46. #
  47. # For files that do exist and have lengths greater than zero, the following 
  48. # actions are performed.
  49. #
  50. #    1) Version numered files are cycled.  That is version 6 is moved to
  51. #       version 7, version is moved to becomes version 6, ... and finally
  52. #       version 0 is moved to version 1.  Both compressed names and
  53. #       uncompressed names are cycled, regardless of -t.  Missing version 
  54. #       files are ignored.
  55. #
  56. #    2) The new file.1 is compressed and is changed subject to 
  57. #       the -m, -u and -g flags.  This step is skipped if the -t flag 
  58. #       was given.
  59. #
  60. #    3) The main file is moved to file.0.
  61. #
  62. #    4) If the -m, -u, -g, -t, or -p flags are given, then the file is
  63. #          touched into existence subject to the given flags.  The -p flag
  64. #          will preserve the original owner, group, and permissions.
  65. #
  66. #    5) The new file.0 is changed subject to the -m, -u and -g flags.
  67. #
  68. # Note: If no -m, -u, -g, -t, or -p is given, then the primary log file is 
  69. #    not created.
  70. #
  71. # Note: Since the version numbers start with 0, version number <cycle>
  72. #       is never formed.  The <cycle> count must be at least 2.
  73. #
  74. # Bugs: If a process is still writing to the file.0 and savelog
  75. #    moved it to file.1 and compresses it, data could be lost.
  76. #    Smail does not have this problem in general because it
  77. #    restats files often.
  78.  
  79. # common location
  80. export PATH=$PATH:/sbin:/bin:/usr/sbin:/usr/bin
  81. COMPRESS="gzip"
  82. COMPRESS_OPTS="-9f"
  83. DOT_Z=".gz"
  84. DATUM=`date +%Y%m%d%H%M%S`
  85.  
  86. # parse args
  87. exitcode=0    # no problems to far
  88. prog=`basename $0`
  89. mode=
  90. user=
  91. group=
  92. touch=
  93. forceclean=
  94. rolldir=
  95. datum=
  96. preserve=
  97. hookscript=
  98. quiet=0
  99. rotateifempty=yes
  100. count=7
  101.  
  102. usage()
  103. {
  104.     echo "Usage: $prog [-m mode] [-u user] [-g group] [-t] [-c cycle] [-p]"
  105.     echo "             [-j] [-C] [-d] [-l] [-r rolldir] [-n] [-q] file ..."
  106.     echo "    -m mode       - chmod log files to mode"
  107.     echo "    -u user       - chown log files to user"
  108.     echo "    -g group   - chgrp log files to group"
  109.     echo "    -c cycle   - save cycle versions of the logfile (default: 7)"
  110.     echo "    -r rolldir - use rolldir instead of . to roll files"
  111.     echo "    -C       - force cleanup of cycled logfiles"
  112.     echo "    -d       - use standard date for rolling"
  113.     echo "    -D       - override date format for -d"
  114.     echo "    -t       - touch file"
  115.     echo "    -l       - don't compress any log files (default: compress)"
  116.     echo "    -p         - preserve mode/user/group of original file"
  117.     echo "    -j         - use bzip2 instead of gzip"
  118.     echo "    -x script  - invoke script with rotated log file in \$FILE"
  119.     echo "    -n         - do not rotate empty files"
  120.     echo "    -q         - suppress rotation message"
  121.     echo "    file        - log file names"
  122. }
  123.  
  124.  
  125. fixfile()
  126. {
  127.     if [ -n "$user" ]; then
  128.     chown -- "$user" "$1"
  129.     fi
  130.     if [ -n "$group" ]; then 
  131.     chgrp -- "$group" "$1"
  132.     fi
  133.     if [ -n "$mode" ]; then 
  134.     chmod -- "$mode" "$1"
  135.     fi
  136. }
  137.  
  138.  
  139. while getopts m:u:g:c:r:CdD:tlphjx:nq opt ; do
  140.     case "$opt" in
  141.     m) mode="$OPTARG" ;;
  142.     u) user="$OPTARG" ;;
  143.     g) group="$OPTARG" ;;
  144.     c) count="$OPTARG" ;;
  145.     r) rolldir="$OPTARG" ;;
  146.     C) forceclean=1 ;;
  147.     d) datum=1 ;;
  148.     D) DATUM=$(date +$OPTARG) ;;
  149.     t) touch=1 ;;
  150.     j) COMPRESS="bzip2"; COMPRESS_OPTS="-9f"; DOT_Z=".bz2" ;;
  151.     x) hookscript="$OPTARG" ;;
  152.     l) COMPRESS="" ;;
  153.     p) preserve=1 ;;
  154.     n) rotateifempty="no" ;;
  155.     q) quiet=1 ;;
  156.     h) usage; exit 0 ;;
  157.     *) usage; exit 1 ;;
  158.     esac
  159. done
  160.  
  161. shift $(($OPTIND - 1))
  162.  
  163. if [ "$count" -lt 2 ]; then
  164.     echo "$prog: count must be at least 2" 1>&2
  165.     exit 2
  166. fi
  167.  
  168. if [ -n "$COMPRESS" ] && [ -z "`which $COMPRESS`"  ]; then
  169.        echo "$prog: Compression binary not available, please make sure '$COMPRESS' is installed" 1>&2
  170.        exit 2
  171. fi
  172.  
  173. # cycle thru filenames
  174. while [ $# -gt 0 ]; do
  175.  
  176.     # get the filename
  177.     filename="$1"
  178.     shift
  179.  
  180.     # catch bogus files
  181.     if [ -e "$filename" ] && [ ! -f "$filename" ]; then
  182.         echo "$prog: $filename is not a regular file" 1>&2
  183.         exitcode=3
  184.         continue
  185.     fi
  186.  
  187.     # if not a file or empty, do nothing major
  188.     # (in the Debian version, we rotate even if empty by default)
  189.     if [ ! -s "$filename" ] && [ "$rotateifempty" != "yes" ]; then
  190.         # if -t was given and it does not exist, create it
  191.         if test -n "$touch" && [ ! -f "$filename" ]; then 
  192.             touch -- "$filename"
  193.             if [ "$?" -ne 0 ]; then
  194.                 echo "$prog: could not touch $filename" 1>&2
  195.                 exitcode=4
  196.                 continue
  197.             fi
  198.             fixfile "$filename"
  199.         fi
  200.         continue
  201.     fi
  202.  
  203.      # be sure that the savedir exists and is writable
  204.     # (Debian default: $savedir is . and not ./OLD)
  205.      savedir=`dirname -- "$filename"`
  206.      if [ -z "$savedir" ]; then
  207.          savedir=.
  208.      fi
  209.     case "$rolldir" in
  210.         (/*)
  211.         savedir="$rolldir"
  212.         ;;
  213.         (*)
  214.         savedir="$savedir/$rolldir"
  215.         ;;
  216.     esac
  217.      if [ ! -d "$savedir" ]; then
  218.          mkdir -p -- "$savedir"
  219.          if [ "$?" -ne 0 ]; then
  220.              echo "$prog: could not mkdir $savedir" 1>&2
  221.              exitcode=5
  222.              continue
  223.          fi
  224.          chmod 0755 -- "$savedir"
  225.      fi
  226.      if [ ! -w "$savedir" ]; then
  227.          echo "$prog: directory $savedir is not writable" 1>&2
  228.          exitcode=7
  229.          continue
  230.      fi
  231.  
  232.     # determine our uncompressed file names
  233.     newname=`basename -- "$filename"`
  234.     newname="$savedir/$newname"
  235.  
  236.     # cycle the old compressed log files
  237.     cycle=$(( $count - 1))
  238.     rm -f -- "$newname.$cycle" "$newname.$cycle$DOT_Z"
  239.     while [ $cycle -gt 1 ]; do
  240.         # --cycle
  241.         oldcycle=$cycle
  242.         cycle=$(( $cycle - 1 ))
  243.         # cycle log
  244.         if [ -f "$newname.$cycle$DOT_Z" ]; then
  245.             mv -f -- "$newname.$cycle$DOT_Z" \
  246.                 "$newname.$oldcycle$DOT_Z"
  247.         fi
  248.         if [ -f "$newname.$cycle" ]; then
  249.             # file was not compressed. move it anyway
  250.             mv -f -- "$newname.$cycle" "$newname.$oldcycle"
  251.         fi
  252.     done
  253.  
  254.     # compress the old uncompressed log if needed
  255.     if [ -f "$newname.0" ]; then
  256.         if [ -z "$COMPRESS" ]; then
  257.             newfile="$newname.1"
  258.             mv -- "$newname.0" "$newfile"
  259.         else
  260.             newfile="$newname.1$DOT_Z"
  261. #            $COMPRESS $COMPRESS_OPTS < $newname.0 > $newfile
  262. #            rm -f $newname.0
  263.             $COMPRESS $COMPRESS_OPTS "$newname.0"
  264.             mv -- "$newname.0$DOT_Z" "$newfile"
  265.         fi
  266.         fixfile "$newfile"
  267.     fi
  268.  
  269.     # compress the old uncompressed log if needed
  270.     if test -n "$datum" && test -n "$COMPRESS"; then
  271.         $COMPRESS $COMPRESS_OPTS -- "$newname".[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]
  272.     fi
  273.  
  274.     # remove old files if so desired
  275.     if [ -n "$forceclean" ]; then
  276.         cycle=$(( $count - 1))
  277.         if [ -z "$COMPRESS" ]; then
  278.             rm -f -- `ls -t -- $newname.[0-9]* | sed -e 1,${cycle}d`
  279.         else
  280.             rm -f -- `ls -t -- $newname.[0-9]*$DOT_Z | sed -e 1,${cycle}d`
  281.         fi
  282.     fi
  283.  
  284.     # create new file if needed
  285.     if [ -n "$preserve" ]; then
  286.         (umask 077
  287.          touch -- "$filename.new"
  288.          chown --reference="$filename" -- "$filename.new"
  289.          chmod --reference="$filename" -- "$filename.new")
  290.         filenew=1
  291.     elif [ -n "$touch$user$group$mode" ]; then
  292.         touch -- "$filename.new"
  293.         fixfile "$filename.new"
  294.         filenew=1
  295.     fi
  296.  
  297.     newfilename="$newname.0"
  298.     # link the file into the file.0 holding place
  299.     if [ -f "$filename" ]; then
  300.         if [ -n "$filenew" ]; then
  301.             if ln -f -- "$filename" "$newfilename"; then
  302.                 mv -- "$filename.new" "$filename"
  303.             else
  304.                 echo "Error hardlinking $filename to $newfilename" >&2
  305.                 exitcode=8
  306.                 continue
  307.             fi
  308.         else
  309.             mv -- "$filename" "$newfilename"
  310.         fi
  311.     fi
  312.     [ ! -f "$newfilename" ] && touch -- "$newfilename"
  313.     fixfile "$newfilename"
  314.     if [ -n "$datum" ]; then
  315.         mv -- "$newfilename" "$newname.$DATUM"
  316.         newfilename="$newname.$DATUM"
  317.     fi
  318.  
  319.     if [ -n "$hookscript" ]; then
  320.       FILE="$newfilename" $SHELL -c "$hookscript" || \
  321.       {
  322.         ret=$?
  323.         test "$quiet" -eq 1 || echo "Hook script failed with exit code $ret." 1>&2
  324.       }
  325.     fi
  326.  
  327.     # report successful rotation
  328.     test "$quiet" -eq 1 || echo "Rotated \`$filename' at `date`."
  329. done
  330. exit $exitcode
  331.